home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 42
/
Amiga Format AFCD42 (Issue 126, Aug 1999).iso
/
-serious-
/
programming
/
other
/
jikes
/
src
/
bytecode.h
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-14
|
12KB
|
296 lines
// $Id: bytecode.h,v 1.4 1999/03/09 14:37:15 shields Exp $
//
// License Agreement available at the following URL:
// http://www.ibm.com/research/jikes.
// Copyright (C) 1996, 1998, International Business Machines Corporation
// and others. All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
#ifndef bytecode_INCLUDED
#define bytecode_INCLUDED
#include <stdio.h>
#include "tuple.h"
#include "ast.h"
#include "class.h"
#include "option.h"
#include "long.h"
#include "op.h"
class TypeSymbol;
class Control;
class Semantic;
class LabelUse
{
public:
int use_length; // length of use (2 or 4 bytes)
int op_offset; // length of use from opcode starting instruction
int use_offset; // offset in code stream of use
LabelUse() : use_length(0),op_offset(0), use_offset(0) {}
LabelUse(int _length, int _op_offset, int _use) :
use_length(_length),op_offset(_op_offset),use_offset(_use) {}
};
class Label
{
public:
int defined; // boolean, set when value is known
int definition; // offset of definition point of label
Tuple<LabelUse> uses;
Label() : defined(0), definition(0) {}
};
class ByteCode : public ClassFile, public StringConstant
{
public:
Control& this_control;
Semantic& this_semantic;
int class_id;
// int bytes; // number of bytes written to file (so far)
// Many java virtual machines, notably Sun's JDK 1.*, don't properly
// handle the case where non-final static fields are initialized
// using the Constant attribute, even though the documentation says
// that this should be done. Define initialize_statics_in_clinit
// to get this behavior to initialize such fields in clinit; otherwise
// fields are initialized using the Constant attribute.
int initialize_statics_in_clinit;
int null_constructor_seen; // set if user supplied null constructor
// if not set, we have to supply null constructor
int line_number;
int last_label_pc; // pc for last (closest to end) label
int last_op_pc; // pc of last operation emitted
int last_op_nop; // set if last operation was NOP.
int this_block_depth; // depth of current block
Code_attribute * code_attribute; // code for current method/??
int stack_depth; // current stack depth;
LineNumberTable_attribute * line_number_table_attribute;
LocalVariableTable_attribute * local_variable_table_attribute;
// Synthetic_attribute * synthetic_attribute;
InnerClasses_attribute * inner_classes_attribute;
MethodSymbol * class_literal_method;
#define METHOD_CLONE 0
#define METHOD_CLONE_GETMESSAGE 1
#define METHOD_CLONE_INIT 2
#define METHOD_STRINGBUFFER_TOSTRING 3
#define METHOD_STRINGBUFFER_INIT 4
#define METHOD_STRINGBUFFER_APPENDCHARARRAY 5
#define METHOD_STRINGBUFFER_APPENDCHAR 6
#define METHOD_STRINGBUFFER_APPENDBOOLEAN 7
#define METHOD_STRINGBUFFER_APPENDINT 8
#define METHOD_STRINGBUFFER_APPENDLONG 9
#define METHOD_STRINGBUFFER_APPENDFLOAT 10
#define METHOD_STRINGBUFFER_APPENDDOUBLE 11
#define METHOD_STRINGBUFFER_APPENDSTRING 12
#define METHOD_STRINGBUFFER_APPENDOBJECT 13
#define METHOD_NUMBER 14
int registered_methods[METHOD_NUMBER];
u2 name_StringNull;
int max_block_depth;
int last_parameter_index; // set to local variable index of last parameter
Label * begin_labels;
Label * break_labels;
Label * continue_labels;
Label * final_labels;
Label * monitor_labels;
Label * test_labels;
int * has_finally_clause;
int * is_synchronized;
int synchronized_blocks; // number of outstanding synchronized blocks
int finally_blocks; // number of outstanding synchronized blocks
BlockSymbol ** block_symbols; // block symbols for current block
int block_depth; // need to reset at start of each method
TypeSymbol * method_type; // return type of method being compiled
void chaos(char *msg); // called when can't proceed
void ProcessAbruptExit(int);
void CompleteLabel(Label& lab);
void DefineLabel(Label& lab);
int IsLabelUsed(Label& lab);
void UseLabel(Label & lab,int length, int op_offset);
// methods to determine type
int IsLocal(AstExpression *);
int IsNull(AstExpression *p);
int IsReferenceType(TypeSymbol *p);
int IsDefaultValue(AstExpression *p);
int IsZero(AstExpression *p);
int GetLHSKind(AstExpression *, MethodSymbol *);
int GetTypeWords(TypeSymbol *);
// methods to load and store values
void LoadLocalVariable(VariableSymbol *);
void LoadLocal(int varno, TypeSymbol * type);
void StoreLocalVariable(VariableSymbol *);
void StoreLocal(int varno, TypeSymbol * type);
int GetConstant(LiteralValue *, TypeSymbol *);
int LoadConstant(AstExpression *);
int LoadLiteral(LiteralValue *,TypeSymbol *);
void LoadReference(AstExpression *);
void LoadShort(int val);
void LoadInteger(int val);
int LoadSimple(int,AstExpression *);
int LoadArrayElement(TypeSymbol * type);
void StoreArrayElement(TypeSymbol * type);
void StoreField(AstExpression *);
void StoreSimple(int,AstExpression *);
// These methods build entries in the constant pool.
u2 BuildDouble(IEEEdouble val);
u2 BuildFieldref(u2 cl_index, u2 nt_index);
u2 BuildFloat(IEEEfloat val);
u2 BuildInteger(int val);
u2 BuildInterfaceMethodref(u2 cl_index, u2 nt_index);
u2 BuildLong(LongInt val);
u2 BuildMethodref(u2 cl_index, u2 nt_index);
u2 BuildNameAndType(u2 name, u2 type);
// make entry in constant pool from wchar string and return its index.
u2 BuildString(u2 si);
u2 BuildUtf8(char *name,int length);
// unlike most methods, which always build a new entry, the
// 'register' methods only build a new entry for a literal if one has net
// yet been built.
u2 RegisterClass(Utf8LiteralValue *);
u2 RegisterClass(char *, int );
u2 RegisterDouble(DoubleLiteralValue *);
u2 RegisterFloat(FloatLiteralValue *);
u2 RegisterInteger(IntLiteralValue *);
u2 RegisterLong(LongLiteralValue *);
u2 RegisterMethod(int);
u2 RegisterString(Utf8LiteralValue *);
u2 RegisterUtf8(Utf8LiteralValue *);
u2 RegisterUtf8(char *, int);
void AddLocalVariableTableEntry(u2,u2,u2,u2,u2); // make entry in local variable table
void SetInnerAttribute(TypeSymbol *); // make entry for InnerClasses attribute
Synthetic_attribute * CreateSyntheticAttribute();
Deprecated_attribute * CreateDeprecatedAttribute();
//
// memory access: reference either
// constant (literal)
// name (includes local varable, or class variable, or field access)
// array
#define LHS_LOCAL 0 // local variable
#define LHS_ARRAY 1 // array (of any kind)
#define LHS_FIELD 2 // instance variable
#define LHS_STATIC 3 // class variable
#define LHS_CLASS_METHOD 4 // access to private variable via class method call
#define LHS_STATIC_METHOD 5 // access to private variable via static method call
// Methods in bc_expr.cpp
int EmitExpression(AstExpression * ast);
void EmitArrayAccessLHS(AstArrayAccess *);
int EmitArrayAccessRHS(AstArrayAccess *);
int EmitArrayCreationExpression(AstArrayCreationExpression *);
int EmitAssignmentExpression(AstAssignmentExpression *, int);
int EmitBinaryExpression(AstBinaryExpression *);
void EmitBinaryOp(AstBinaryExpression *, int iop, int lop, int fop, int dop);
int EmitCastExpression(AstCastExpression *);
void EmitCast(TypeSymbol *, TypeSymbol *);
int EmitClassInstanceCreationExpression(AstClassInstanceCreationExpression *, int);
int EmitConditionalExpression(AstConditionalExpression *);
int EmitFieldAccess(AstFieldAccess *);
void EmitFieldAccessLHS(AstExpression *);
void EmitFieldAccessLHSBase(AstExpression *);
int EmitMethodInvocation(AstMethodInvocation *, int);
void EmitNewArray(int,TypeSymbol *);
void EmitCloneArray(AstMethodInvocation *);
int EmitPostUnaryExpression(AstPostUnaryExpression *,int);
void Emit